package org.example.core.Service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.example.Util.UserUtil;
import org.example.api.ComfyuiApi;
import org.example.core.Dto.Text2ImageCanelResponseDto;
import org.example.core.Dto.Text2ImageResDto;
import org.example.core.Dto.Text2ImageResponseDto;
import org.example.core.Dto.common.Result;
import org.example.core.Mapper.UserFundMapper;
import org.example.core.Mapper.UserResultMapper;
import org.example.core.Service.*;
import org.example.core.pojo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.example.Ollama.client.service.ollamaService;
import retrofit2.Call;
import retrofit2.Response;

import java.io.IOException;
import java.util.List;

import static org.example.core.Service.impl.RedisServiceImpl.*;

@Service
@Slf4j
public class Text2ImageServiceImpl implements Text2ImageService {
    public static final String COMFYUI_CLIENT_ID = "star-graph";

    @Autowired
    private ollamaService ollamaService;
    @Autowired
    private FreeMarkerService freeMarkerService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private UserFundRecordService userFundRecordService;
    @Autowired
    private UserResultMapper userResultMapper;
    @Autowired
    private ComfyuiApi comfyuiApi;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    UserFundMapper userMapper;

    @Override
    public ComfyuiTask getComfyuiTask(Text2ImageResDto dto) throws TemplateException, IOException {

        //实现将星图传递下来的格式转换为ComfyuiModel类型
        ComfyuiModel model=BeanUtil.toBean(dto, ComfyuiModel.class);

        model.setModelName(dto.modelName());
        model.setSamplerName(dto.samplerName());
        model.setScheduler(dto.scheduler());
        model.setWidth(dto.width());
        model.setHeight(dto.height());
        //将prompt翻译为英文
        model.setPropmt(String.format("(8k, best quality, masterpiece), (high detailed skin),%s", ollamaService.translate(model.getPropmt())));
        if(StrUtil.isNotEmpty(model.getReverse())){
            model.setReverse(ollamaService.translate(model.getReverse()));
        }
        model.setReverse(String.format("%s,bad face,naked,bad finger,bad arm,bad leg,bad eye", model.getReverse()));
        //将model通过freemarker渲染为Json字符串
        String s = freeMarkerService.renderText2Image(model);
        ComfyuiRequestDto requestDto = new ComfyuiRequestDto(COMFYUI_CLIENT_ID,JSON.parseObject(s));
        ComfyuiTask task = new ComfyuiTask(dto.getClientId(), requestDto);
        task.setUserId(UserUtil.getUser().getId());
        task.setSize(dto.getSize());
        return task;
    }

    @Override
    public Text2ImageResponseDto TextToImage(Text2ImageResDto dto) throws TemplateException, IOException {
        if(dto.getSize()<1){
            throw new RuntimeException("输入参数有误");
        }
        userFundRecordService.pointsFreeze(UserUtil.getUser().getId(),dto.getSize());
        ComfyuiTask comfyuiTask = getComfyuiTask(dto);
        comfyuiTask = redisService.addQueueTask(comfyuiTask);
        Text2ImageResponseDto text2ImageResponseDto = new Text2ImageResponseDto();
        text2ImageResponseDto.setPid(comfyuiTask.getId());
        text2ImageResponseDto.setQueueIndex(comfyuiTask.getIndex());
        return text2ImageResponseDto;
    }

    @Override
    public List<UserResult> list(int page, int size) {
        Long id = UserUtil.getUser().getId();
        System.out.println("用户ID为："+id);
        Page<UserResult> userResultPage = new Page<>(page, size);
        LambdaQueryWrapper<UserResult> eq = Wrappers.<UserResult>lambdaQuery().eq(UserResult::getUserId, id);
        List<UserResult> userResults = userResultMapper.selectList(eq);
        return userResults;
    }

    @Override
    public String canel(Text2ImageCanelResponseDto text2ImageResponseDto) throws IOException {
        String pid = text2ImageResponseDto.getTempId();
        if(StrUtil.isEmpty(pid)){
            return "没有该任务的信息";
        }
        String task= stringRedisTemplate.opsForValue().get(TASK_KEY_PREFIX + pid);
        if(StrUtil.isEmpty(task)){return "没有该任务的信息";}
        ComfyuiTask comfyuiTask = JSON.parseObject(task, ComfyuiTask.class);
        String s = stringRedisTemplate.opsForValue().get(RUN_TASK_KEY +comfyuiTask.getPromptId());
        if(StrUtil.isNotEmpty(s)){
            Call<Void> hashMapCall = comfyuiApi.interruptTask();
            Response<Void> execute = hashMapCall.execute();
            if(execute.isSuccessful()){
                stringRedisTemplate.delete(RUN_TASK_KEY +comfyuiTask.getPromptId());
            }
        }else
        {
            //1、取消Redis中任务队列的任务和具体任务信息
            stringRedisTemplate.opsForZSet().remove(DISTRIBUTED_QUEUE_KEY,pid);
        }
        Long userId = comfyuiTask.getUserId();
        int size = comfyuiTask.getSize();
        stringRedisTemplate.delete(TASK_KEY_PREFIX+pid);
        userFundRecordService.freezeReturn(userId,size);
        return "取消成功";
    }

    @Override
    public Result<Object> proprity(Text2ImageCanelResponseDto text2ImageResponseDto) {
        String tempId = text2ImageResponseDto.getTempId();
        Long index = text2ImageResponseDto.getIndex();
        String s = stringRedisTemplate.opsForValue().get(TASK_KEY_PREFIX + tempId);
        if(StrUtil.isEmpty(s)){
            return Result.error("没有该任务的信息");
        }
        ComfyuiTask comfyuiTask = JSON.parseObject(s, ComfyuiTask.class);
        LambdaQueryWrapper<UserFund> eq = Wrappers.<UserFund>lambdaQuery().eq(UserFund::getUserId, comfyuiTask.getUserId());
        UserFund userFund = userMapper.selectOne(eq);
        //判断用户积分是否充足
        if(userFund.getScore()-5<0){
            return Result.error("用户积分不足");
        }
        //判断当前任务是否在运行中
        String s1 = stringRedisTemplate.opsForValue().get(RUN_TASK_KEY + comfyuiTask.getPromptId());
        if(StrUtil.isNotEmpty(s1)){
            return Result.error("当前任务正在运行中,无法插队");
        }
        comfyuiTask.setIndex(comfyuiTask.getIndex()-10L);
        stringRedisTemplate.opsForZSet().incrementScore(DISTRIBUTED_QUEUE_KEY,comfyuiTask.getId(),-10);
        stringRedisTemplate.opsForValue().set(TASK_KEY_PREFIX + tempId, JSON.toJSONString(comfyuiTask));
        userFundRecordService.directDeduction(comfyuiTask.getUserId(),5);
        Long Id=comfyuiTask.getIndex()>0?comfyuiTask.getIndex():1;
        return Result.ok(Id);
    }

}
